# coding: utf-8

#证书
import os
import datetime
import File
import RSA_op
import SHA256_op
import FTP_op

#根据使用者姓名和公钥生成申请文件
def apply_certificate(ftp, name):
    #判断公钥文件是否存在
    public_file = name+"_public.key"
    if os.path.exists(public_file)==False:
        return -1
    public_key = File.read_file_hex(public_file)
    #填写申请文件的姓名和公钥字段
    write_name = name + "_apply.csr"
    f = open(write_name,"w")
    f.write("user name:" + name + '\n')
    f.write("user public key:" + public_key + '\n')
    f.close()
    #登录远程FTP并且上传申请文件
    FTP_op.login_ftp(ftp, 'user_upload')
    FTP_op.ftp_upload(ftp, name + "_apply.csr")
    FTP_op.quit_ftp(ftp)
    #一切成功函数返回1
    return 1

#用户下载证书
def download_certificate(ftp, name):
    #用户登录FTP
    FTP_op.login_ftp(ftp, 'user_download')
    file_list = ftp.nlst()
    if (name+'_CA.csr' in file_list):   #查找是否有自己的证书，有则下载
        FTP_op.ftp_download(ftp, name+'_CA.csr')
    else:
        return -1  #没有生产则返回错误
    FTP_op.quit_ftp(ftp)
    return 1   #下载成功返回1

#校验证书
def verify_certificate(ftp, name):
    #name = input("请输入证书使用者姓名:")
    apply_file = name+"_CA.csr"
    t_str = ''
    try:
        with open(apply_file, "r") as f:
            for i in range(4):
                t_str += f.readline()
            t_start = f.readline()
            t_str += t_start
            t_stop = f.readline()
            t_str += t_stop
            t_sign = f.readline()[5:]
        #print('t_str:'+t_str)
    except:
        # print("证书不存在，请检查输入\n")
        return -1

    #下载CA的公钥与吊销列表
    FTP_op.login_ftp(ftp, 'ca_public')
    FTP_op.ftp_download(ftp, 'CA_public.key')
    file_list = ftp.nlst()
    if ('CA_cancel.crl' in file_list):
        FTP_op.ftp_download(ftp, 'CA_cancel.crl')
    FTP_op.quit_ftp(ftp)

    #检查证书是否在吊销列表
    pub_key  = File.read_file_dec('CA_public.key')
    id_num = t_str.find('user id')
    u_id = t_str[id_num+8:][:64]
    u_id = int(u_id, 16)
    #print('u_id:'+str(u_id))
    try:
        with open('CA_cancel.crl', 'r') as f:
            while True:
                t_id = f.readline()
                if not t_id:
                    break
                t_id = int(t_id, 16)
                t_decrypt = RSA_op.exp_mode(t_id, 65537, pub_key)
                #print("t_decrypt:"+str(t_decrypt))
                if u_id == t_decrypt:
                    # print("该证书已被吊销\n")
                    return -2
    except:
        print("提示：未找到吊销列表")

    #验证证书时间
    t_start = t_start[11:].replace("\n",'')
    t_stop = t_stop[9:].replace("\n",'')
    #print(t_start+t_stop)
    UTC_FORMAT = "%Y-%m-%dT%H:%M:%S.%f"
    nowTime = datetime.datetime.utcnow()
    startTime = datetime.datetime.strptime(t_start, UTC_FORMAT)
    endTime = datetime.datetime.strptime(t_stop, UTC_FORMAT)
    if ((startTime - nowTime).days >0):
        # print("该证书未生效")
        return -3
    elif ((endTime - nowTime).days <0):
        # print("该证书已过期")
        return -4
    
    #验证签名
    t_sign = int(t_sign, 16)
    #print('t_sign:'+str(t_sign))
    #pub_key  = File.read_file_dec('CA_public.key')
    t_sha = SHA256_op.cal_sha256(t_str)
    #print('t_sha:'+t_sha)
    t_decrypt = RSA_op.exp_mode(t_sign, 65537, pub_key)
    t_decrypt = hex(t_decrypt)[2:].upper()
    #print('t_decrypt:'+str(t_decrypt))
    if(t_sha == t_decrypt):
        # print("验证通过\n")
        return 1
    else:
        # print("验证不通过\n")
        return 0

#签名文件
def sign_file(name, filename):
    #查找待签名文件、公钥、私钥是否存在，不存在返回错误值
    try:
        f = open(filename,'r')
        f.close()
        f = open(name+'_private.key','r')
        f.close()
        f = open(name+'_public.key','r')
        f.close()
    except:
        return -1
    sha = SHA256_op.cal_file_sha256(filename)  #计算文件的SHA256的值
    sha = int(sha, 16)
    #读取公钥和私钥
    pri_key = File.read_file_dec(name+'_private.key')
    pub_key  = File.read_file_dec(name+'_public.key')
    #计算得到签名值
    t_sign = RSA_op.exp_mode(sha, pri_key, pub_key)
    File.write_file(name+'_'+filename+".sign", t_sign)
    return 1 #返回正确值

#验证文件的签名
def verify_sign_file(name, filename):
    #检查证书文件、原文件、签名文件是否存在
    try:
        f = open(name+"_CA.csr",'r')
        f.close()
        f = open(filename,'r')
        f.close()
        f = open(name+'_'+filename+".sign",'r')
        f.close()
    except:
        return -1

    #计算文件的SHA256
    t_sha = SHA256_op.cal_file_sha256(filename)
    #从已有签名文件中读取签名值
    t_sign = File.read_file_dec(name+'_'+filename+".sign")
    #从证书文件中读取公钥
    with open(name+"_CA.csr", "r") as f:
        f.readline()
        pub_key = f.readline()
    pub_key=int(pub_key[16:], 16) #将读取的公钥转换为十进制
    t_decrypt = RSA_op.exp_mode(t_sign, 65537, pub_key)  #利用公钥进行解密
    t_decrypt = hex(t_decrypt)[2:].upper()
    #比较计算得到的SHA256值和解密得到的SHA256值是否相等
    if(t_sha == t_decrypt):
        #验证通过
        return 1
    else:
        # 验证不通过
        return 0
    